<script lang="tsx">
import { defineComponent, reactive, ref } from "vue";
import { FormInst } from "naive-ui";
export default defineComponent({
	name: "BasicForm",
	props: {
		config: {
			default: {},
			type: Object,
		},
	},
	setup(props, { expose }) {
		// console.log(props.config);
		const labelWidth: number = props.config.labelWidth;
		const isVertical: boolean = props.config.isVertical;
		const labelPlacement: string = props.config.labelPlacement;
		const formItems: Record<string, any>[] = props.config.formItems;
		const rules: Record<string, any> = props.config.rules;
		const model = reactive<Record<string, any>>({});
		const formRef = ref<FormInst | null>(null);

		type ItemType = string | number | Array<string> | null;
		const itemInit = (item) => {
			let value: ItemType = null;
			switch (item.type) {
				case "CheckBox":
					value = [];
					break;
				case "Date":
					value = Date.now();
					break;
				case "Time":
					value = new Date().getTime();
					break;
				default:
					value = "";
			}
			model[item.field] = value;
		};
		// 表单重置
		const reset = () => {
			formItems.forEach((item) => {
				itemInit(item);
			});
		};
		// 初始化表单
		const formInit = () => {
			formItems.forEach((item) => {
				if (item.value) {
					model[item.field] = item.value;
				} else {
					itemInit(item);
				}
			});
			console.log("model",model);
		};

		formInit();

		// 渲染控件
		const renderItem = (item: Record<string, any>) => {
			switch (item.type) {
				case "Input":
					return (
						<n-input
							type={item.inputType}
							v-model:value={model[item.field]}
							placeholder={item?.placeholder}
							style={{ width: item.inputWidth }}
							show-password-on={item?.show_password_on}
						/>
					);

				case "Select":
					return (
						<n-select
							style={{ width: item.selectWidth }}
							v-model:value={model[item.field]}
							placeholder={item.placeholder}
							options={item.options}
						/>
					);

				case "Switch":
					return <n-switch v-model:value={model[item.field]} />;
				case "CheckBox":
					return (
						<n-checkbox-group v-model:value={model[item.field]}>
							<n-space>
								{item.options.map((o) => {
									return <n-checkbox value={o.value}>{o.label}</n-checkbox>;
								})}
							</n-space>
						</n-checkbox-group>
					);
				case "RadioBox":
					return (
						<n-radio-group v-model:value={model[item.field]} name={item.name}>
							<n-space>
								{item.options.map((o) => {
									return <n-radio value={o.value}>{o.label}</n-radio>;
								})}
							</n-space>
						</n-radio-group>
					);
				case "TextArea":
					return (
						<n-input
							v-model:value={model[item.field]}
							placeholder={item.placeholder}
							type={item.inputType}
							autosize={{
								minRows: item.autosize.minRows,
								maxRows: item.autosize.maxRows,
							}}
						/>
					);
				case "Date":
					return (
						<n-date-picker
							v-model:value={model[item.field]}
							type={item.inputType}
						/>
					);
				case "Time":
					return <n-time-picker v-model:value={model[item.field]} />;
			}
		};

		const renderItems = (formItems: Record<string, any>[]) => {
			return formItems.map((item) => {
				return (
					<n-form-item
						label={item.labelName}
						label-style={item.labelStyle}
						path={item.field}
					>
						{renderItem(item)}
					</n-form-item>
				);
			});
		};
		const getFormRef = () => {
			return formRef.value;
		};
		expose({
			getFormRef,
			reset,
		});
		return () => (
			<n-space vertical={isVertical}>
				<n-form
					ref={formRef}
					model={model}
					rules={rules}
					label-placement={labelPlacement}
					require-mark-placement="right-hanging"
					label-width={labelWidth}
				>
					{renderItems(formItems)}
				</n-form>
			</n-space>
		);
	},
});
</script>

<style lang="less" scoped></style>
